﻿using BCCommon;
using BCCommon.Enums;
using BCCommon.PaymentEnums;
using BCData.TMS.RedPacket.RedPacket;
using BCData.TMS.RedPacket.RedPacketType;
using BCDto.Sim.Admin.Admin;
using BCDto.TMS.RedPacket.RedPacketType;
using BCDto.TMS.RedPacket.RedPacketType.RedPacketTypeRequest;
using BCEntity.Common.EntityNameConst;
using BCEntity.TMS.RedPacket.RedPacket;
using BCEntity.TMS.RedPacket.RedPacketType;
using BCService.TMS.AgentWallet;
using BCService.Utils;
using System;
using System.Collections.Generic;

namespace BCService.TMS.RedPacket.RedPacketType
{
    public class RedPacketTypeService: IRedPacketTypeService
    {
        private readonly IRedPacketTypeData redPacketTypeData;
        private readonly IDatabaseContext databaseContext;
        private readonly IRedPacketData redPacketData;
        private readonly IRedisService redisService;
        private readonly IAgentWalletService agentWalletService;
        private readonly string keyType = string.Format("{0}", EntityNameConst.RedPacketTypeEntity);
        private readonly string key = string.Format("{0}", EntityNameConst.RedPacketEntity);
        public RedPacketTypeService(IDatabaseContext databaseContext,
            IRedPacketTypeData redPacketTypeData,
            IRedisService redisService,
            IRedPacketData redPacketData,
            IAgentWalletService agentWalletService)
        {
            this.databaseContext = databaseContext;
            this.redPacketTypeData = redPacketTypeData;
            this.redisService = redisService;
            this.redPacketData = redPacketData;
            this.agentWalletService = agentWalletService;
        }

        public RedPacketTypeDto Create(RedPacketTypeRequestDto requestDto, AdminDto admin)
        {
            if (admin.AgentRecord == null)
            {
                throw new ArgumentException(" 用户验证失败,错误操作 ");
            }
            var isExist = redPacketData.GetRedPacket(requestDto.RedPacketAmount,admin.AgentRecord.AgentRecordId).Result != null;
            if (isExist)
            {
                throw new ArgumentException(" 当前红包类型已存在,请去补充 ");
            }
            var typeEntity = new RedPacketTypeEntity
            {
                RedPacketType = requestDto.RedPacketType,
                RedPacketAmount = requestDto.RedPacketAmount,
                GrundlagenType = requestDto.GrundlagenType.ToString(),
                CreateTime = DateTime.Now,
                CreateAdminId = admin.AdminId,
                CreateAdminName = admin.FullName,
                UpdateTime = DateTime.Now,
                EditAdminId = admin.AdminId,
                EditAdminName = admin.FullName,
                Enabled = true,
                AgentRecordId = admin.AgentRecord.AgentRecordId,
            };

            var amount = requestDto.RedPacketCount * requestDto.RedPacketAmount;
            string orderNo = Guid.NewGuid().ToString();
            this.databaseContext.BeginTransaction();
            agentWalletService.Pay(admin, amount, "红包发放", FlowType.RedPacket, PaymentChannelType.Balance,
               FlowDirectionType.Outlay, orderNo);
            var result = this.redPacketTypeData.InsertAsync(typeEntity).GetAwaiter().GetResult();
            var redPacketEntity = new RedPacketEntity
            {
                RedPacketTypeId = result.RedPacketTypeId,
                RedPacketType = result.RedPacketType,
                RedPacketAmount = result.RedPacketAmount,
                GrundlagenType = result.GrundlagenType,
                RedPacketName = result.RedPacketAmount.ToString("G0") + "元红包",
                RedPackCount = requestDto.RedPacketCount,
                RemainCount = requestDto.RedPacketCount,
                ReceivedCount = 0,
                Enabled = true,
                CreateTime = DateTime.Now,
                CreateAdminId = admin.AdminId,
                CreateAdminName = admin.FullName,
                UpdateTime = DateTime.Now,
                EditAdminId = admin.AdminId,
                EditAdminName = admin.FullName,
                AgentRecordId = admin.AgentRecord.AgentRecordId,
            };
            this.redPacketData.InsertAsync(redPacketEntity).GetAwaiter().GetResult();
            this.databaseContext.Commit();
            this.redisService.DeleteMultipleKey(keyType, false);
            this.redisService.DeleteMultipleKey(key, false);
            return result.As<RedPacketTypeDto>();
        }

        public IEnumerable<RedPacketTypeDto> GetList(bool? isEnabled)
        {
            string cacheKey = this.redisService.GetKey(keyType, isEnabled);
            var resultRedis = this.redisService.TryGet(cacheKey, () =>
            {
                var result = this.redPacketTypeData.GetList(isEnabled).Result;
                return result.As<IEnumerable<RedPacketTypeDto>>();
            }, TimeSpan.FromDays(1));
            return resultRedis;

        }

        public RedPacketTypeDto GetSingle(long redPacketTypeId)
        {
            string cacheKey = this.redisService.GetKey(keyType, redPacketTypeId);
            var resultRedis = this.redisService.TryGet(cacheKey, () =>
            {
                var entity = this.redPacketTypeData.GetSingle(redPacketTypeId).GetAwaiter().GetResult();
                if (entity == null)
                {
                    throw new ArgumentException(" 获取红包类型失败 ");
                }
                return entity.As<RedPacketTypeDto>();
            }, TimeSpan.FromDays(1));
            return resultRedis;
        }

        public PageableList<RedPacketTypeDto> Query(bool? isEnabled, int pageIndex, int pageSize)
        {
            string cacheKey = this.redisService.GetKey(keyType, isEnabled, pageIndex, pageSize);
            var resultRedis = this.redisService.TryGet(cacheKey, () =>
            {
                var (list, dataCount) = this.redPacketTypeData.Query(isEnabled, pageIndex, pageSize).GetAwaiter().GetResult();
                var result = new PageableList<RedPacketTypeDto>
                {
                    Count = dataCount,
                    Items = list.As<IEnumerable<RedPacketTypeDto>>(),
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    ServerTime = DateTime.Now,
                };
                return result;
            }, TimeSpan.FromDays(1));
            return resultRedis;
        }

        public RedPacketTypeDto Update(long redPacketTypeId, RedPacketTypeRequestDto requestDto, AdminDto admin)
        {
            var entity = this.redPacketTypeData.GetSingle(redPacketTypeId).GetAwaiter().GetResult();
            if (entity == null)
            {
                throw new ArgumentException(" 获取红包类型失败 ");
            }
            entity.RedPacketType = requestDto.RedPacketType;
            entity.RedPacketAmount = requestDto.RedPacketAmount;
            entity.GrundlagenType = requestDto.GrundlagenType.ToString();
            entity.UpdateTime = DateTime.Now;
            entity.EditAdminId = admin.AdminId;
            entity.EditAdminName = admin.FullName;
            var result = this.redPacketTypeData.UpdateAsync(entity).GetAwaiter().GetResult();
            this.redisService.DeleteMultipleKey(keyType, false);
            return result.As<RedPacketTypeDto>();
        }

    }
}
